<?php

class ImagesServiceImpl implements ImagesService {

    private $fullServerPath = false;

    function __construct($fullServerPath) {
        $this->fullServerPath = $fullServerPath;
    }

    public function getFoldersTree($base, $name, $level) {
        $folders = array();
        return $this->getByPath($base, $name, $level);
    }

    private function getByPath($path, $name, $level) {
        $children = array();
        $dir=@opendir($this->fullServerPath . $path);
        if((($level == -1) || ($level > 0))) {
            while($file = @readdir($dir)) {
                if($file != "." && $file != ".." && substr($file, 0, 1) != '.' && is_dir($this->fullServerPath . $path . "/" . $file)) {
                    $level = $level != -1 ? ($level -1) : -1;
                    $newPath = strlen($path) == 0 ? $file : $path . "/" .  $file;
                    $children[] = $this->getByPath($newPath, $file, $level);
                    usort($children, array("ImagesServiceImpl", Config::$folders_sort));

                }
            }
        }
        $niceName = $this->getNiceName($name);
        $url = Config::$script_url . (strlen($path) == 0 ? "" : "?album=". $path);  //TODO
        $createTime = filemtime($this->fullServerPath . $path);
        $coverImage = ServicesFactory::getCoverImagesService()->getCoverImage($path);
        return new Folder($name, $url, $createTime, $children, $coverImage);
    }

    public function getImages($path) {
        $currentDir = $this->fullServerPath . $path;
        $dir=@opendir($currentDir);
        $images = array();
        while($file=@readdir($dir)) {
            if($file != "." && $file != ".." && substr($file, 0, 1) != '.' && is_file($currentDir . "/" . $file)) {

                $fileExt = $this->file_ext($file);
                $fileName = $this->file_name($file);

                $allow = array("jpg", "gif", "png");
                $fileExtType = str_replace("jpeg", "jpg", strtolower($fileExt));
                if (in_array($fileExtType, $allow)) {
                    $url = $currentDir . "/" . $file;
                    $thumb = $url;
                    $lowRes = $url;

                    $thumbUrl = $currentDir . "/.thumbs/" . $fileName . "." . $fileExt;
                    if(!file_exists($thumbUrl)) {
                        $thumb = $this->createThumb($currentDir . "/.thumbs", $currentDir, $fileName, $fileExt, Config::$thumbmax);
                    } else {
                        $thumb = $thumbUrl;
                    }

                    $lowresUrl = $currentDir . "/.lowres/" . $fileName . "." . $fileExt;
                    if(!file_exists($lowresUrl)) {
                        $lowRes = $this->createThumb($currentDir . "/.lowres", $currentDir, $fileName, $fileExt, Config::$lowresmax);
                    } else {
                        $lowRes = $lowresUrl;
                    }

                    $createTime = filemtime($url);
                    $exif = new Exif($url);

                    $images[] = new Image($file, $url, $createTime, $exif, $thumb, $lowRes);
                }
            }
        }
        usort($images, array("ImagesServiceImpl", "nameCompare"));
        return $images;
    }

    // TODO: maybe use http://wideimage.sourceforge.net/ istead of this mess
    function createThumb($pathToThumbs, $pathToOriginals, $file_name, $file_ext, $max_size) {

        if(!is_dir($pathToThumbs)) {
            mkdir($pathToThumbs);
        }

        //The GD Libary only supports jpg and gif really, well it can only make a gif a jpg. There are other ways like image magik, but not many have it so I didn't include that. So dent anything that isn't a gif or jpg :(.
        $allow = array("jpg", "gif", "png");
        $file = $file_name . "." . $file_ext;
        $fileExtType = str_replace("jpeg", "jpg", strtolower($file_ext));
        if(in_array($fileExtType, $allow)) {
            $imgData = getimagesize($pathToOriginals . "/" . $file);
            $imgWidth = $imgData[0];
            $imgHeight = $imgData[1];
            $thumbRealWidth = $imgWidth;
            $thumbRealHeight = $imgHeight;
            if($imgWidth > $max_size || $imgHeight > $max_size) {
                $imgratio = $imgWidth / $imgHeight;
                if($imgratio > 1) {
                    $thumbRealWidth = $max_size;
                    $thumbRealHeight = $max_size / $imgratio;
                } else {
                    $thumbRealWidth = $max_size * $imgratio;
                    $thumbRealHeight = $max_size;
                }
            }

            $imgResized = imagecreatetruecolor($thumbRealWidth, $thumbRealHeight);
            if ($fileExtType == "gif") {
                $imgsrc = imagecreatefromgif($pathToOriginals . "/" . $file);
            } elseif ( $fileExtType == "jpg" ) {
                $imgsrc=imagecreatefromjpeg($pathToOriginals . "/" . $file);
            } elseif ( $fileExtType == "png" ) {
                $imgsrc=imagecreatefrompng($pathToOriginals . "/" . $file);
            }

            imagecopyresized($imgResized, $imgsrc, 0, 0, 0, 0, $thumbRealWidth, $thumbRealHeight, $imgData[0], $imgData[1]);

            $new_file = $pathToThumbs . "/" . $file_name . "." . $file_ext;
            $fh = fopen($new_file, 'w');
            fclose($fh);
            if($fileExtType == "gif") {
                if (!imagegif($imgResized, $new_file)) {
                    throw new Exception("Failed to create image " . $new_file);
                }
            } elseif ($fileExtType == "jpg") {
                if (!imagejpeg($imgResized, $new_file, Config::$jpg_quality)) {
                    throw new Exception("Failed to create image " . $new_file);
                }
            } elseif ($fileExtType == "png") {
                if (!imagepng($imgResized, $new_file, 0)) {
                    throw new Exception("Failed to create image " . $new_file);
                }
            }
            imagedestroy($imgsrc);
            imagedestroy($imgResized);
            return $new_file;
        } 
    }

    private function getNiceName($name) {
        $find=array("_","-");
        $replace=array(" "," ");
        return str_replace($find, $replace, $name);
    }

    private function file_name($key) {
        $key=strrev(substr(strstr(strrev($key), "."), 1));
        return($key);
    }

    private function file_ext($key) {
        $key=substr(strrchr($key, "."), 1);
        return($key);
    }
    private static function nameCompare($a, $b) {
        if($a->getName() == $b->getName()) {
            return 0;
        }
        return $a->getName() < $b->getName() ? -1 : 1;
    }

    private static function timeCompare($a, $b) {
        if($a->getCreateTime() == $b->getCreateTime()) {
            return 0;
        }
        return $a->getCreateTime() > $b->getCreateTime() ? -1 : 1;
    }

    public function getFoldersNavigation($path) {
        $nav = array();
        global $home_link, $files_path, $script_url, $open_folder, $close_folder;
        $album = $path;
        if(!is_dir(Config::$full_server . $path)) {
            $album = "";
        }
        $find=array("_","-");
        $replace=array(" "," ");
        $folder=@explode("/", $album);

        $nav[] = new Folder(Config::$home_link, Config::$script_url, NULL, NULL, NULL);

        $count=@count($folder);
        $path="";
        for($i=0 ; $i<$count; $i++) {
            if($folder[$i]) {
                $path.=$folder[$i]."/";
                $nav[] = new Folder($folder[$i], Config::$script_url . "?album=" . $path, NULL, NULL, NULL);
            }
        }
        return $nav;
    }
}
?>
